package com.photoeditor.demo.model.bean;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;

import com.common.base.ComponentContext;
import com.common.base.utils.DeviceUtils;
import com.photoeditor.R;
import com.photoeditor.demo.model.image.collage.templet.Line;
import com.photoeditor.demo.model.image.collage.util.MathUtil;
import com.photoeditor.demo.model.image.emoji.LocalStickerData;
import com.photoeditor.demo.model.image.util.ImageHelper;
import com.photoeditor.demo.ui.widget.stash.container.ContainerView;
import com.photoeditor.demo.model.bean.stash.ContainerBean;

import java.util.ArrayList;


/**
 * 用于存储添加Emoji图片的Bean
 */
public class EditEmojiBean implements ContainerBean {

    /**
     * Emoji的最小大小
     */
    public final static int SMALLEST_SIZE = ComponentContext.getContext().getResources().getDimensionPixelSize(R.dimen.scale_smallest_size);

    public final static float MAX_SIZE = ImageHelper.SCREEN_WIDTH * 1.5f;

    private float mMaxSize;

    /**
     * 按钮的大小
     */
    public final static int RADIUS = ComponentContext.getContext().getResources().getDimensionPixelSize(R.dimen.image_edit_operation_button_size);

    /**
     * Emoji的大小
     */
    public final int EMOJI_WIDTH;
    public final int EMOJI_HEIGHT;

    /**
     * 当前Bean的Rect
     */
    private RectF mRect;

    /**
     * 用于保存旋转的角度
     */
    private float mDegree;
    private float mRealDegree;

    /**
     * 用于点击时 点击位置的映射
     */
    private Matrix mMatrix;


    /**
     * 操作按钮的Rect
     */
    private RectF mButtonRect;

    /**
     * 操作按钮的Rect
     */
    private RectF mDeleteRect;

    /**
     * 设置按钮的Rect
     */
    private RectF mSettingRect;

    /**
     * 是否正被点击
     */
    private boolean mIsTouch;

    /**
     * emojiId
     */
    private EmojiBean mEmojiBean;


    private RectF mLeftOperationRect;
    private RectF mTopOperationRect;
    private RectF mRightOperationRect;
    private RectF mBottomOperationRect;

    private Canvas mCanvas;

    //设置里面的变化bitmap
    private Bitmap mBitmap;

    //设置外面的最终bitmap
    private Bitmap mSrcBitmap;

    //保存上次操作的bitmap
    private Bitmap mCacheBitmap;

    private Paint mBitmapPaint;

    private Paint mBrushPaint;

    private Path mPath = new Path();

    //private ArrayList<Path> mCachePathList = new ArrayList<>();

    private ArrayList<PathBean> mPathList;

    //参数调节历史
    private ArrayList<AdjustParam> mParamList;

    //上一次参数
    private AdjustParam mLastParam;

    private int mPaintWidthProgress = 50;

    public static final float PAINT_WIDTH_UNIT = DeviceUtils.dip2px(ComponentContext.getContext(), 1f) * 0.25f;

    public static final int PAINT_STYLE_STIFF = 0;
    public static final int PAINT_STYLE_SOFT = 1;
    private int mPaintStyle = PAINT_STYLE_STIFF;

    public static final int PAINT_MODE_ERASE = 0;
    public static final int PAINT_MODE_REVERSE = 1;
    private int mPaintMode = PAINT_MODE_ERASE;
    private BlurMaskFilter mBlurMaskFilter;
    private PorterDuffXfermode mEraseXfermode;
    private PorterDuffXfermode mReverseXfermodeStiff;
    private PorterDuffXfermode mReverseXfermodeSoft;

    private boolean mShowSrc = false;

    //是否在使用原始的sticker图片
    private boolean mHasUseSrcBitmap = true;
    //镜像的值
    private float mFlipX;
    private float mFlipY;

    public EditEmojiBean(RectF mDrawableRect, EmojiBean bean){
        this(mDrawableRect.centerX(), mDrawableRect.centerY(), bean);
    }

    public EditEmojiBean(float centerX, float centerY, EmojiBean bean) {
        mEmojiBean = bean;
        mDegree = 0;
        mRealDegree = mDegree;
        mMatrix = new Matrix();
        mRect = new RectF();
        mButtonRect = new RectF();
        mDeleteRect = new RectF();
        mSettingRect = new RectF();
        mLeftOperationRect = new RectF();
        mTopOperationRect = new RectF();
        mRightOperationRect = new RectF();
        mBottomOperationRect = new RectF();
        mIsTouch = false;
        EMOJI_WIDTH = bean.getEditEmojiWidth();
        EMOJI_HEIGHT = bean.getEditEmojiHeight();
        mMaxSize = MAX_SIZE;
        mFlipX = 1;
        mFlipY = 1;

        mSrcBitmap = LocalStickerData.getInstance().getBitmap(bean);

        mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBitmapPaint.setFilterBitmap(true);

        mBrushPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBrushPaint.setStyle(Paint.Style.STROKE);
        mBrushPaint.setStrokeWidth(mPaintWidthProgress * PAINT_WIDTH_UNIT);
        mBrushPaint.setColor(0x00ffffff);
        mEraseXfermode = new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);
        mBrushPaint.setXfermode(mEraseXfermode);
        mBrushPaint.setStrokeCap(Paint.Cap.ROUND);
        mBrushPaint.setStrokeJoin(Paint.Join.ROUND);

        mReverseXfermodeStiff = new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP);
        mReverseXfermodeSoft = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
        mPath = new Path();

        mLastParam = new AdjustParam(0, 1, 1, 0);

        init(centerX, centerY);
        mCacheBitmap = mSrcBitmap.copy(Bitmap.Config.ARGB_8888, true);
        mBitmap = mSrcBitmap.copy(Bitmap.Config.ARGB_8888, true);
    }

    private void init(float centerX, float centerY) {

        mRect.left = centerX - EMOJI_WIDTH / 2;
        mRect.top = centerY - EMOJI_HEIGHT / 2;
        mRect.right = mRect.left + EMOJI_WIDTH;
        mRect.bottom = mRect.top + EMOJI_HEIGHT;
        mLastRectBeforeScale.set(mRect);
        countOtherRect();
    }

    public EditEmojiBean(RectF rect, EmojiBean bean, float degree) {
        mEmojiBean = bean;
        mDegree = degree;
        mRealDegree = mDegree;
        mMatrix = new Matrix();
        mRect = new RectF();
        mButtonRect = new RectF();
        mDeleteRect = new RectF();
        mSettingRect = new RectF();
        mLeftOperationRect = new RectF();
        mTopOperationRect = new RectF();
        mRightOperationRect = new RectF();
        mBottomOperationRect = new RectF();
        mIsTouch = false;
        EMOJI_WIDTH = bean.getEditEmojiWidth();
        EMOJI_HEIGHT = bean.getEditEmojiHeight();
        mMaxSize = MAX_SIZE;
        mFlipX = 1;
        mFlipY = 1;

        mSrcBitmap = LocalStickerData.getInstance().getBitmap(bean);

        mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBitmapPaint.setFilterBitmap(true);

        mBrushPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBrushPaint.setStyle(Paint.Style.STROKE);
        mBrushPaint.setStrokeWidth(mPaintWidthProgress * PAINT_WIDTH_UNIT);
        mBrushPaint.setColor(0x00ffffff);
        mEraseXfermode = new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);
        mBrushPaint.setXfermode(mEraseXfermode);
        mBrushPaint.setStrokeCap(Paint.Cap.ROUND);
        mBrushPaint.setStrokeJoin(Paint.Join.ROUND);

        mReverseXfermodeStiff = new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP);
        mReverseXfermodeSoft = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
        mPath = new Path();

        mLastParam = new AdjustParam(0, 1, 1, 0);

        mRect.set(rect);
        countOtherRect();
        mLastRectBeforeScale.set(mRect);

        mCacheBitmap = mSrcBitmap.copy(Bitmap.Config.ARGB_8888, true);
        mBitmap = mSrcBitmap.copy(Bitmap.Config.ARGB_8888, true);
    }

    /**
     * 擦除操作
     */
    public void drawBitmap() {
        mBitmap.recycle();
        int w = (int) mRect.width();
        int h = (int) mRect.height();

        if ( w <= 0 || h <= 0) {
            return;
        }
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);

        mCanvas.drawBitmap(mCacheBitmap, null, new Rect(0, 0, w, h), mBitmapPaint);

        /*if (mPaintStyle == PAINT_STYLE_SOFT) {
            for (Path path : mCachePathList) {
                mCanvas.drawPath(path, mBrushPaint);
            }
        } else {
            mCanvas.drawPath(mPath, mBrushPaint);
        }*/
        mCanvas.drawPath(mPath, mBrushPaint);

    }

    //路径开始
    public void setPathStart(float x, float y) {
        Matrix m = new Matrix();
        m.setRotate(-mDegree, mRect.width() / 2, mRect.height() / 2);
        float[] dest = new float[2];
        m.mapPoints(dest, new float[]{x, y});
        mPath.moveTo(dest[0], dest[1]);
        drawBitmap();
    }

    //路径移动
    public void setPathMove(float x1, float y1, float x2, float y2) {
        Matrix m = new Matrix();
        m.setRotate(-mDegree, mRect.width() / 2, mRect.height() / 2);
        float[] point1 = new float[2];
        float[] point2 = new float[2];
        m.mapPoints(point1, new float[]{x1, y1});
        m.mapPoints(point2, new float[]{x2, y2});
        /*if (mPaintStyle == PAINT_STYLE_SOFT) {
            mPath.rewind();
            mPath.moveTo(point1[0], point1[1]);
            mPath.quadTo(point2[0], point2[1], (point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2);
            mCachePathList.add(new Path(mPath));
        } else {
            mPath.quadTo(point1[0], point1[1], (point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2);
        }*/
        mPath.quadTo(point1[0], point1[1], (point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2);
        drawBitmap();
    }

    //保存路径
    public void savePath() {
        if (mPathList == null) {
            mPathList = new ArrayList<>();
        }
        /*if (mPaintStyle == PAINT_STYLE_SOFT) {
            mPathList.add(new PathBean(mCachePathList, mBrushPaint));
        } else {
            mCachePathList.add(new Path(mPath));
            mPathList.add(new PathBean(mCachePathList, mBrushPaint));
        }*/
        mPathList.add(new PathBean(mPath, mBrushPaint));
        mPath.reset();
        //mCachePathList.clear();

        mCacheBitmap.recycle();
        mCacheBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true);
    }

    public void saveParam() {
        if (mParamList == null) {
            mParamList = new ArrayList<>();
        }
        mParamList.add(new AdjustParam(mLastParam));
    }

    public void removeLastParam() {
        if (mParamList.size() - 2 < 0) {
            mLastParam.set(0, 1, 1, 0);
        } else {
            mLastParam.set(mParamList.get(mParamList.size() - 2));
        }
        if (mParamList.size() - 1 >= 0) {
            mParamList.remove(mParamList.get(mParamList.size() - 1));
        }
    }

    public void removeLastPaint() {
        if (mPathList.size() - 1 >= 0) {
            mPathList.remove(mPathList.get(mPathList.size() - 1));

            if (mPathList.size() == 0) {
                resetPaint();
            } else {
                mBitmap.recycle();
                mBitmap = Bitmap.createBitmap((int) mRect.width(), (int) mRect.height(), Bitmap.Config.ARGB_8888);
                mCanvas = new Canvas(mBitmap);

                mCanvas.drawBitmap(mSrcBitmap, null, new Rect(0, 0, (int) mRect.width(), (int) mRect.height()), mBitmapPaint);

                if (mPathList != null) {
                    for (PathBean pathBean : mPathList) {
                        /*for (Path path : pathBean.paths) {
                            mCanvas.drawPath(path, pathBean.paint);
                        }*/
                        mCanvas.drawPath(pathBean.path, pathBean.paint);
                    }
                }

                mCacheBitmap.recycle();
                mCacheBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true);
            }

        }
    }

    //设置色调
    public void setTone(float tone) {
        mLastParam.tone = tone;
    }

    //设置饱和度
    public void setSaturation(float saturation) {
        mLastParam.saturation = saturation;
    }

    //设置亮度
    public void setBrightness(float brightness) {
        mLastParam.brightness = brightness;
    }

    //设置透明度
    public void setAlpha(float alpha) {
        mLastParam.alpha = alpha;
    }

    //设置画笔宽度  progress
    public void setPaintWidth(int progress) {
        mPaintWidthProgress = progress;
        mBrushPaint.setStrokeWidth(mPaintWidthProgress * PAINT_WIDTH_UNIT);
        if (mPaintStyle == PAINT_STYLE_SOFT) {
            try {
                // 线上crash，new BlurMaskFilter出现java.lang.IllegalArgumentException，先try住
                mBlurMaskFilter = new BlurMaskFilter(mBrushPaint.getStrokeWidth() / 2, BlurMaskFilter.Blur.NORMAL);
                mBrushPaint.setMaskFilter(mBlurMaskFilter);
            } catch (Exception e){
            }
        }
    }

    //设置硬笔还是软笔模式
    public void setPaintStyle(int style) {
        this.mPaintStyle = style;
        if (mPaintStyle == PAINT_STYLE_SOFT) {
            try {
                // 线上crash，new BlurMaskFilter出现java.lang.IllegalArgumentException，先try住
                mBlurMaskFilter = new BlurMaskFilter(mBrushPaint.getStrokeWidth() / 2, BlurMaskFilter.Blur.NORMAL);
                mBrushPaint.setMaskFilter(mBlurMaskFilter);
                if (mPaintMode == PAINT_MODE_REVERSE) {
                    mBrushPaint.setXfermode(mReverseXfermodeSoft);
                    mBrushPaint.setColor(0xffffffff);
                } else {
                    mBrushPaint.setXfermode(mEraseXfermode);
                    mBrushPaint.setColor(0x00ffffff);
                }
            } catch (Exception e) {
            }
        } else {
            mBrushPaint.setMaskFilter(null);
            if (mPaintMode == PAINT_MODE_REVERSE) {
                mBrushPaint.setXfermode(mReverseXfermodeStiff);
                mBrushPaint.setColor(0xffffffff);
            } else {
                mBrushPaint.setXfermode(mEraseXfermode);
                mBrushPaint.setColor(0x00ffffff);
            }
        }
    }

    //设置擦除还是还原模式
    public void setPaintMode(int mode) {
        this.mPaintMode = mode;
        if (mPaintMode == PAINT_MODE_REVERSE) {
            //还原
            mBrushPaint.setShader(new BitmapShader(
                    Bitmap.createScaledBitmap(mSrcBitmap, (int) mRect.width(), (int) mRect.height(), true),
                    Shader.TileMode.CLAMP,
                    Shader.TileMode.CLAMP));
            if (mPaintStyle == PAINT_STYLE_SOFT) {
                mBlurMaskFilter = new BlurMaskFilter(mBrushPaint.getStrokeWidth() / 2, BlurMaskFilter.Blur.NORMAL);
                mBrushPaint.setMaskFilter(mBlurMaskFilter);
                mBrushPaint.setXfermode(mReverseXfermodeSoft);
                mBrushPaint.setColor(0xffffffff);
            } else {
                mBrushPaint.setMaskFilter(null);
                mBrushPaint.setXfermode(mReverseXfermodeStiff);
                mBrushPaint.setColor(0xffffffff);
            }
        } else {
            //擦除
            mBrushPaint.setShader(null);
            mBrushPaint.setXfermode(mEraseXfermode);
            if (mPaintStyle == PAINT_STYLE_SOFT) {
                float radius = mBrushPaint.getStrokeWidth() / 2;
                radius = Math.max(1, radius);
                mBlurMaskFilter = new BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL);
                mBrushPaint.setMaskFilter(mBlurMaskFilter);
                mBrushPaint.setColor(0x00ffffff);
            } else {
                mBrushPaint.setMaskFilter(null);
                mBrushPaint.setColor(0x00ffffff);
            }
        }
    }

    //重置参数
    public void reset() {

        resetParam();

        resetPaint();
    }

    public void resetParam() {
        mLastParam.set(0, 1, 1, 0);
        if (mParamList != null) {
            mParamList.clear();
        }
    }

    public void resetPaint() {
        mCacheBitmap.recycle();
        mCacheBitmap = mSrcBitmap.copy(Bitmap.Config.ARGB_8888, true);
        setPaintMode(PAINT_MODE_ERASE);
        setPaintStyle(PAINT_STYLE_STIFF);
        setPaintWidth(50);
        if (mPathList != null) {
            mPathList.clear();
        }
        drawBitmap();
    }

    //保存图片
    public void save() {
        replaceSrcBitmap();

        mBitmap.recycle();
        mBitmap = mSrcBitmap.copy(Bitmap.Config.ARGB_8888, true);
        mCacheBitmap.recycle();
        mCacheBitmap = mSrcBitmap.copy(Bitmap.Config.ARGB_8888, true);

        mLastParam.set(0, 1, 1, 0);

        setPaintMode(PAINT_MODE_ERASE);
        setPaintStyle(PAINT_STYLE_STIFF);
        setPaintWidth(50);

        if (mPathList != null) {
            mPathList.clear();
        }

        if (mParamList != null) {
            mParamList.clear();
        }

        drawBitmap();
    }

    public void onDestroy() {
        if (!mHasUseSrcBitmap) {
            if (mSrcBitmap != null && !mSrcBitmap.isRecycled()) {
                mSrcBitmap.recycle();
            }
        }
        if (mCacheBitmap != null && !mCacheBitmap.isRecycled()) {
            mCacheBitmap.recycle();
        }
        if (mBitmap != null && !mBitmap.isRecycled()) {
            mBitmap.recycle();
        }
    }

    @Override
    public int getType() {
        return ContainerView.BEAN_TYPE_STICKER;
    }

    private RectF mLastRectBeforeScale = new RectF();

    @Override
    public RectF getLastRectBeforeScale() {
        return mLastRectBeforeScale;
    }

    public void replaceSrcBitmap() {
        if (mHasUseSrcBitmap) {
            mHasUseSrcBitmap = false;
        } else {
            mSrcBitmap.recycle();
        }
        try {
            // 线上crash，createBitmap出现java.lang.IllegalArgumentException，应该高宽出问题，先try住
            mSrcBitmap = Bitmap.createBitmap((int) mRect.width(), (int) mRect.height(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(mSrcBitmap);
            ColorMatrix hueMatrix = new ColorMatrix();
            //修改色相   0 red 1 green 2 blue
            hueMatrix.setRotate(0, mLastParam.tone);
            hueMatrix.setRotate(1, mLastParam.tone);
            hueMatrix.setRotate(2, mLastParam.tone);
            //修改饱和度
            ColorMatrix saturationMatrix = new ColorMatrix();
            saturationMatrix.setSaturation(mLastParam.saturation);
            //修改亮度
            ColorMatrix lumMatrix = new ColorMatrix();
            //r g b a    1 表示全不透明
            lumMatrix.setScale(mLastParam.brightness, mLastParam.brightness, mLastParam.brightness, 1 - mLastParam.alpha);

            //组合Matrix
            ColorMatrix imageMatrix = new ColorMatrix();
            imageMatrix.postConcat(hueMatrix);
            imageMatrix.postConcat(saturationMatrix);
            imageMatrix.postConcat(lumMatrix);

            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setFilterBitmap(true);

            paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
            canvas.drawBitmap(mBitmap, null, new Rect(0, 0, (int) mRect.width(), (int) mRect.height()), paint);
        } catch (Exception e){
        }
    }

    public AdjustParam getLastParam() {
        return mLastParam;
    }

    public Bitmap getBitmap() {
        if (mShowSrc) {
            return mSrcBitmap;
        } else {
            return mBitmap;
        }
    }

    public float getPaintWidthRadius(){
        return mBrushPaint.getStrokeWidth() / 2;
    }

    public void setShowSrc(boolean showSrc) {
        mShowSrc = showSrc;
    }

    public boolean isShowSrc() {
        return mShowSrc;
    }

    public float getTone() {
        return mLastParam.tone;
    }

    public float getSaturation() {
        return mLastParam.saturation;
    }

    public float getBrightness() {
        return mLastParam.brightness;
    }

    public float getAlpha() {
        return mLastParam.alpha;
    }

    public int getPaintWidthProgress() {
        return mPaintWidthProgress;
    }

    public int getPaintStyle() {
        return mPaintStyle;
    }

    public int getPaintMode() {
        return mPaintMode;
    }

    /**
     * 旋转
     *
     * @param degree
     */
    public void setDegree(float degree) {
        mRealDegree += degree;
        float remain = mRealDegree % 90;
        if(Math.abs(remain) >= 0 && Math.abs(remain) < 3) {
            this.mDegree = mRealDegree - remain;
        } else if(Math.abs(remain) > 87) {
            if (remain > 0) {
                this.mDegree = mRealDegree + 90 - remain;
            } else {
                this.mDegree = mRealDegree - 90 - remain;
            }
        } else {
            mDegree = mRealDegree;
        }
    }

    public void setDegreeDirect(float degree) {
        this.mDegree = degree;
        mRealDegree = mDegree;
    }

    @Override
    public void setFlip(boolean horizontal, float value) {
        if(horizontal){
            mFlipX = value;
        } else {
            mFlipY = value;
        }
    }

    @Override
    public float getFlipX() {
        return mFlipX;
    }

    @Override
    public float getFlipY() {
        return mFlipY;
    }

    public float getDegree() {
        return mDegree;
    }

    /**
     * 获取当前Rect
     *
     * @return
     */
    public RectF getRect() {
        return mRect;
    }

    /**
     * 获取当前ButtonRect
     *
     * @return
     */
    public RectF getButtonRect() {
        return mButtonRect;
    }

    public RectF getSettingRect() {
        return mSettingRect;
    }

    /**
     * 获取当前DeleteRect
     *
     * @return
     */
    public RectF getDeleteRect() {
        return mDeleteRect;
    }

    /**
     * 正在点击
     *
     * @return
     */
    public boolean isTouch() {
        return mIsTouch;
    }

    /**
     * 设置mIsTouch
     *
     * @param mIsTouch
     */
    public void setIsTouch(boolean mIsTouch) {
        this.mIsTouch = mIsTouch;
    }

    /**
     * 获取EmojiId
     */
    public EmojiBean getEmojiBean() {
        return mEmojiBean;
    }

    /**
     * 用于获取当前旋转的Matrix
     *
     * @return
     */
    public Matrix getMatrix() {
        mMatrix.setRotate(-mDegree, mRect.centerX(), mRect.centerY());
        return mMatrix;
    }

    /**
     * 放大缩小
     *
     * @param scale
     */
    public void setScale(float scale) {

        Matrix m = new Matrix();
        m.setScale(scale, scale, mRect.centerX(), mRect.centerY());
        RectF rect = new RectF();
        m.mapRect(rect, mRect);
        if (rect.width() >= SMALLEST_SIZE && rect.width() <= mMaxSize) {
            mRect = rect;
            mLastRectBeforeScale.set(mRect);
            countOtherRect();
        }
    }

    @Override
    public void scaleTo(RectF lastRectF, float scale) {
        Matrix m = new Matrix();
        m.setScale(scale, scale, mRect.centerX(), mRect.centerY());
        m.mapRect(mRect, lastRectF);

        countOtherRect();
    }

    public void move(float dx, float dy) {
        mRect.offset(dx, dy);
        mButtonRect.offset(dx, dy);
        mDeleteRect.offset(dx, dy);
        mSettingRect.offset(dx, dy);
        mLeftOperationRect.offset(dx, dy);
        mRightOperationRect.offset(dx, dy);
        mTopOperationRect.offset(dx, dy);
        mBottomOperationRect.offset(dx, dy);
        mLastRectBeforeScale.set(mRect);
    }

    @Override
    public void moveTo(RectF lastRectF, float dx, float dy) {
        mRect.left = lastRectF.left - dx;
        mRect.right = lastRectF.right - dx;
        mRect.top = lastRectF.top - dy;
        mRect.bottom = lastRectF.bottom - dy;

        countOtherRect();
    }

    public static void doScale(RectF rect, RectF buttonRect, RectF deleteRect, RectF dstRect, RectF dstButtonRect, RectF dstDeleteRect, Matrix matrix, Matrix cacheMatrix) {
        matrix.mapRect(dstRect, rect);
        float scale = dstRect.width() / rect.width();
        float dx = dstRect.centerX() - rect.centerX();
        float dy = dstRect.centerY() - rect.centerY();

        dstButtonRect.set(buttonRect);
        dstDeleteRect.set(deleteRect);
        cacheMatrix.reset();
        cacheMatrix.setScale(scale, scale, rect.centerX(), rect.centerY());
        cacheMatrix.mapRect(dstRect, rect);

        if (rect.width() >= SMALLEST_SIZE) {
            dstButtonRect.left = dstRect.right - RADIUS;
            dstButtonRect.top = dstRect.bottom - RADIUS;
            dstButtonRect.right = dstRect.right + RADIUS;
            dstButtonRect.bottom = dstRect.bottom + RADIUS;

            dstDeleteRect.left = dstRect.left - RADIUS;
            dstDeleteRect.top = dstRect.top - RADIUS;
            dstDeleteRect.right = dstRect.left + RADIUS;
            dstDeleteRect.bottom = dstRect.top + RADIUS;
        }

        dstRect.offset(dx, dy);
        dstButtonRect.offset(dx, dy);
        dstDeleteRect.offset(dx, dy);
    }

    public static void doScale(RectF rect, RectF dstRect, RectF baseRect, RectF supperRect, Matrix matrix, Matrix cacheMatrix, RectF viewRect) {
        RectF a = new RectF(rect);
        a.offset(-viewRect.left, -viewRect.top);

        Matrix matrixB = new Matrix(matrix);

        RectF supperRect1 = new RectF(supperRect);
        supperRect1.offset(-viewRect.left, -viewRect.top);

        float bscale = supperRect1.width() / baseRect.width();
        Matrix m = new Matrix();
        m.postScale(bscale, bscale, baseRect.centerX(), baseRect.centerY());
        m.postTranslate(supperRect1.centerX() - baseRect.centerX(), supperRect1.centerY() - baseRect.centerY());
        m.invert(m);

        matrixB.preConcat(m);

        matrixB.mapRect(dstRect, a);

        float scale = dstRect.width() / a.width();
        float dx = dstRect.centerX() - a.centerX();
        float dy = dstRect.centerY() - a.centerY();

        cacheMatrix.reset();
        cacheMatrix.setScale(scale, scale, a.centerX(), a.centerY());
        cacheMatrix.mapRect(dstRect, a);

        dstRect.offset(dx, dy);
        dstRect.offset(viewRect.left, viewRect.top);
    }

    private Matrix mLastMatrix;

    /**
     * 用于缩放时的处理
     *
     * @param baseRect    是图片的真实Rect
     * @param supperRect  是显示的真实Rect
     * @param matrix      是ImageView的ImageMatrix
     * @param cacheMatrix 一个用于操作的缓存Matrix
     * @param viewRect    ImageView当前的Rect
     *                    <p>
     *                    这个方法的原理是  Matrix cur = Matrix last * Matrix B
     *                    Matrix B = Matrix last 倒置 * Matrix cur
     *                    求到Matrix B然后转化成scale和Move就行
     */
    public void doScaleMove(RectF baseRect, RectF supperRect, Matrix matrix, Matrix cacheMatrix, RectF viewRect) {
        if (mLastMatrix == null) {
            RectF dstRect = new RectF();
            RectF a = new RectF(mRect);
            a.offset(-viewRect.left, -viewRect.top);

            //防止坐标对他的影响
            RectF supperRect1 = new RectF(supperRect);
            supperRect1.offset(-viewRect.left, -viewRect.top);
            //aScale是 baseRect -> supperRect的缩放值
            float bScale = supperRect1.width() / baseRect.width();
            Matrix m = new Matrix();
            m.postScale(bScale, bScale, baseRect.centerX(), baseRect.centerY());
            m.postTranslate(supperRect1.centerX() - baseRect.centerX(), supperRect1.centerY() - baseRect.centerY());
            m.invert(m);

            //matrixA是去掉 从baseRect转换到supperRect后的Matrix
            Matrix matrixA = new Matrix(matrix);
            matrixA.preConcat(m);
            matrixA.mapRect(dstRect, a);

            float scale = dstRect.width() / a.width();
            float dx = dstRect.centerX() - a.centerX();
            float dy = dstRect.centerY() - a.centerY();

            cacheMatrix.reset();
            cacheMatrix.setScale(scale, scale, a.centerX(), a.centerY());
            cacheMatrix.mapRect(dstRect, a);

            dstRect.offset(viewRect.left, viewRect.top);
            dstRect.offset(dx, dy);

            if (mRect.width() >= SMALLEST_SIZE) {
                mRect = dstRect;
                countOtherRect();
            }

            mLastMatrix = new Matrix();
            mLastMatrix.set(matrix);
        } else {
            RectF dstRect = new RectF();
            RectF a = new RectF(mRect);
            a.offset(-viewRect.left, -viewRect.top);

            mLastMatrix.invert(mLastMatrix);
            //matrixA是去掉 从baseRect转换到supperRect后的Matrix
            Matrix matrixA = new Matrix(matrix);
            matrixA.preConcat(mLastMatrix);
            matrixA.mapRect(dstRect, a);

            float scale = dstRect.width() / a.width();
            float dx = dstRect.centerX() - a.centerX();
            float dy = dstRect.centerY() - a.centerY();

            cacheMatrix.reset();
            cacheMatrix.setScale(scale, scale, a.centerX(), a.centerY());
            cacheMatrix.mapRect(dstRect, a);

            dstRect.offset(viewRect.left, viewRect.top);
            dstRect.offset(dx, dy);

            if (mRect.width() >= SMALLEST_SIZE) {
                mRect = dstRect;
                countOtherRect();
            }
            mLastMatrix.set(matrix);
        }
    }

    /**
     * 设置当前的Matrix
     *
     * @param matrix
     */
    public void setLastMatrix(Matrix matrix) {
        if (mLastMatrix == null) {
            mLastMatrix = new Matrix();
        }
        mLastMatrix.set(matrix);
    }

    /**
     * 处理旋转和缩放
     *
     * @param downX
     * @param downY
     * @param nowX
     * @param nowY
     */
    public void dealScaleAndRotation(float downX, float downY, float nowX, float nowY) {
        float px = mRect.centerX();
        float py = mRect.centerY();

        float x1 = downX - px;
        float y1 = downY - py;

        float x2 = nowX - px;
        float y2 = nowY - py;

        float scale = (float) (Math.sqrt(x2 * x2 + y2 * y2) / Math.sqrt(x1 * x1 + y1 * y1));

        double degree1 = MathUtil.getDegree(px, py, downX, downY, px + 1, py);

        double degree2 = MathUtil.getDegree(px, py, nowX, nowY, px + 1, py);

        int location1 = MathUtil.getLocation(x1, y1);
        int location2 = MathUtil.getLocation(x2, y2);

        /**
         * 这里是以px, py作为原点   如果是一二象限则 是逆时针旋转  取负值
         *
         * 如果是三四象限则顺时针角度比较小 取正值
         */
        if (location2 == 1 || location2 == 2) {
            degree2 = -degree2;
        }

        if (location1 == 1 || location1 == 2) {
            degree1 = -degree1;
        }

        double degree = degree2 - degree1;

        setScale(scale);
        setDegree((float) degree);
    }

    /**
     * 计算其他辅助juzhen
     */
    private void countOtherRect() {
        mButtonRect.left = mRect.right - RADIUS;
        mButtonRect.top = mRect.bottom - RADIUS;
        mButtonRect.right = mRect.right + RADIUS;
        mButtonRect.bottom = mRect.bottom + RADIUS;

        mSettingRect.left = mRect.left - RADIUS;
        mSettingRect.top = mRect.bottom - RADIUS;
        mSettingRect.right = mRect.left + RADIUS;
        mSettingRect.bottom = mRect.bottom + RADIUS;

        mDeleteRect.left = mRect.left - RADIUS;
        mDeleteRect.top = mRect.top - RADIUS;
        mDeleteRect.right = mRect.left + RADIUS;
        mDeleteRect.bottom = mRect.top + RADIUS;

        mLeftOperationRect.left = mRect.left - RADIUS;
        mLeftOperationRect.top = (mRect.top + mRect.bottom) / 2 - RADIUS;
        mLeftOperationRect.right = mRect.left + RADIUS;
        mLeftOperationRect.bottom = (mRect.top + mRect.bottom) / 2 + RADIUS;

        mRightOperationRect.left = mRect.right - RADIUS;
        mRightOperationRect.top = (mRect.top + mRect.bottom) / 2 - RADIUS;
        mRightOperationRect.right = mRect.right + RADIUS;
        mRightOperationRect.bottom = (mRect.top + mRect.bottom) / 2 + RADIUS;

        mTopOperationRect.left = (mRect.left + mRect.right) / 2 - RADIUS;
        mTopOperationRect.top = mRect.top - RADIUS;
        mTopOperationRect.right = (mRect.left + mRect.right) / 2 + RADIUS;
        mTopOperationRect.bottom = mRect.top + RADIUS;

        mBottomOperationRect.left = (mRect.left + mRect.right) / 2 - RADIUS;
        mBottomOperationRect.top = mRect.bottom - RADIUS;
        mBottomOperationRect.right = (mRect.left + mRect.right) / 2 + RADIUS;
        mBottomOperationRect.bottom = mRect.bottom + RADIUS;
    }

    /**
     * 原理是根据当前Rect的四个角的点 计算出 旋转后的点, 然后通过dx的移动计算出目标点
     * 然后用目标的点  再反映射出  当前Rect的值即是我们所需要的
     *
     * @param dx 这个dx是通过反向计算后一定会left平移的距离
     */
    public void operationLeft(float dx) {
        float leftTopPoint[] = new float[]{mRect.left, mRect.top};
        float rightTopPoint[] = new float[]{mRect.right, mRect.top};
        float leftbottomPoint[] = new float[]{mRect.left, mRect.bottom};
        float rightBottomPoint[] = new float[]{mRect.right, mRect.bottom};

        float leftTopPointMap[] = new float[2];
        float rightTopPointMap[] = new float[2];
        float leftbottomPointMap[] = new float[2];
        float rightBottomPointMap[] = new float[2];
        Matrix m1 = new Matrix();
        m1.postRotate(getDegree(), mRect.centerX(), mRect.centerY());
        m1.mapPoints(leftTopPointMap, leftTopPoint);
        m1.mapPoints(rightTopPointMap, rightTopPoint);
        m1.mapPoints(leftbottomPointMap, leftbottomPoint);
        m1.mapPoints(rightBottomPointMap, rightBottomPoint);

        Line line = new Line(leftTopPointMap[0], -leftTopPointMap[1], rightTopPointMap[0], -rightTopPointMap[1]);
        double x, y;
        if (line.isHrizontal()) {
            x = dx;
            y = 0;
        } else if (line.isVertical()) {
            x = 0;
            y = dx;
        } else {
            int location1 = MathUtil.getLocation(leftTopPointMap[0] - rightTopPointMap[0], leftTopPointMap[1] - rightTopPointMap[1]);
            double degree1 = MathUtil.getDegreeFromX(line, location1);
            if (degree1 < 90) {
                double radians = Math.toRadians(degree1);
                if (dx < 0) {
                    x = -dx * Math.cos(radians);
                    y = dx * Math.sin(radians);
                } else {
                    x = -dx * Math.cos(radians);
                    y = dx * Math.sin(radians);
                }
            } else if (degree1 < 180) {
                double radians = Math.toRadians(180 - degree1);
                if (dx < 0) {
                    x = dx * Math.cos(radians);
                    y = dx * Math.sin(radians);
                } else {
                    x = dx * Math.cos(radians);
                    y = dx * Math.sin(radians);
                }
            } else if (degree1 < 270) {
                double radians = Math.toRadians(270 - degree1);
                if (dx < 0) {
                    x = dx * Math.sin(radians);
                    y = -dx * Math.cos(radians);
                } else {
                    x = dx * Math.sin(radians);
                    y = -dx * Math.cos(radians);
                }
            } else {
                double radians = Math.toRadians(360 - degree1);
                if (dx < 0) {
                    x = -dx * Math.cos(radians);
                    y = -dx * Math.sin(radians);
                } else {
                    x = -dx * Math.cos(radians);
                    y = -dx * Math.sin(radians);
                }
            }
        }
        float leftTopPointMapResult[] = new float[2];
        float leftbottomPointMapResult[] = new float[2];
        leftTopPointMapResult[0] = leftTopPointMap[0] + (float) x;
        leftTopPointMapResult[1] = leftTopPointMap[1] + (float) y;
        leftbottomPointMapResult[0] = leftbottomPointMap[0] + (float) x;
        leftbottomPointMapResult[1] = leftbottomPointMap[1] + (float) y;

        RectF rectF = MathUtil.point2RectF(leftTopPointMapResult, leftbottomPointMapResult, rightTopPointMap, rightBottomPointMap);
        m1.reset();
        m1.postRotate(-getDegree(), rectF.centerX(), rectF.centerY());
        m1.mapPoints(leftTopPointMapResult);
        m1.mapPoints(leftbottomPointMapResult);
        m1.mapPoints(rightTopPointMap);
        m1.mapPoints(rightBottomPointMap);
        rectF = MathUtil.point2RectF(leftTopPointMapResult, leftbottomPointMapResult, rightTopPointMap, rightBottomPointMap);

        if (rectF.width() >= SMALLEST_SIZE) {
            mRect = new RectF(rectF);
            mRect.left = Math.min(mRect.left, mRect.right);
            countOtherRect();
        }
    }

    /**
     * 原理同上
     *
     * @param dx
     */
    public void operationRight(float dx) {
        float leftTopPoint[] = new float[]{mRect.left, mRect.top};
        float rightTopPoint[] = new float[]{mRect.right, mRect.top};
        float leftbottomPoint[] = new float[]{mRect.left, mRect.bottom};
        float rightBottomPoint[] = new float[]{mRect.right, mRect.bottom};

        float leftTopPointMap[] = new float[2];
        float rightTopPointMap[] = new float[2];
        float leftbottomPointMap[] = new float[2];
        float rightBottomPointMap[] = new float[2];
        Matrix m1 = new Matrix();
        m1.postRotate(getDegree(), mRect.centerX(), mRect.centerY());
        m1.mapPoints(leftTopPointMap, leftTopPoint);//计算map后的点
        m1.mapPoints(rightTopPointMap, rightTopPoint);
        m1.mapPoints(leftbottomPointMap, leftbottomPoint);
        m1.mapPoints(rightBottomPointMap, rightBottomPoint);

        Line line = new Line(leftTopPointMap[0], -leftTopPointMap[1], rightTopPointMap[0], -rightTopPointMap[1]);
        double x, y;
        if (line.isHrizontal()) {
            x = dx;
            y = 0;
        } else if (line.isVertical()) {
            x = 0;
            y = dx;
        } else {
            int location1 = MathUtil.getLocation(rightTopPointMap[0] - leftTopPointMap[0], rightTopPointMap[1] - leftTopPointMap[1]);
            double degree1 = MathUtil.getDegreeFromX(line, location1);
            if (degree1 < 90) {
                double radians = Math.toRadians(degree1);
                if (dx < 0) {
                    x = dx * Math.cos(radians);
                    y = -dx * Math.sin(radians);
                } else {
                    x = dx * Math.cos(radians);
                    y = -dx * Math.sin(radians);
                }
            } else if (degree1 < 180) {
                double radians = Math.toRadians(180 - degree1);
                if (dx < 0) {
                    x = -dx * Math.cos(radians);
                    y = -dx * Math.sin(radians);
                } else {
                    x = -dx * Math.cos(radians);
                    y = -dx * Math.sin(radians);
                }
            } else if (degree1 < 270) {
                double radians = Math.toRadians(270 - degree1);
                if (dx < 0) {
                    x = -dx * Math.sin(radians);
                    y = dx * Math.cos(radians);
                } else {
                    x = -dx * Math.sin(radians);
                    y = dx * Math.cos(radians);
                }
            } else {
                double radians = Math.toRadians(360 - degree1);
                if (dx < 0) {
                    x = dx * Math.cos(radians);
                    y = dx * Math.sin(radians);
                } else {
                    x = dx * Math.cos(radians);
                    y = dx * Math.sin(radians);
                }
            }
        }
        float rightTopPointMapResult[] = new float[2];
        float rightbottomPointMapResult[] = new float[2];
        rightTopPointMapResult[0] = rightTopPointMap[0] + (float) x;
        rightTopPointMapResult[1] = rightTopPointMap[1] + (float) y;
        rightbottomPointMapResult[0] = rightBottomPointMap[0] + (float) x;
        rightbottomPointMapResult[1] = rightBottomPointMap[1] + (float) y;

        RectF rectF = MathUtil.point2RectF(leftTopPointMap, leftbottomPointMap, rightTopPointMapResult, rightbottomPointMapResult);
        m1.reset();
        m1.postRotate(-getDegree(), rectF.centerX(), rectF.centerY());
        m1.mapPoints(leftTopPointMap);
        m1.mapPoints(leftbottomPointMap);
        m1.mapPoints(rightTopPointMapResult);
        m1.mapPoints(rightbottomPointMapResult);
        rectF = MathUtil.point2RectF(leftTopPointMap, leftbottomPointMap, rightTopPointMapResult, rightbottomPointMapResult);

        if (rectF.width() >= SMALLEST_SIZE) {
            mRect = new RectF(rectF);
            mRect.left = Math.min(mRect.left, mRect.right);
            countOtherRect();
        }
    }

    /**
     * 原理同上
     *
     * @param dy
     */
    public void operationTop(float dy) {
        float leftTopPoint[] = new float[]{mRect.left, mRect.top};
        float rightTopPoint[] = new float[]{mRect.right, mRect.top};
        float leftbottomPoint[] = new float[]{mRect.left, mRect.bottom};
        float rightBottomPoint[] = new float[]{mRect.right, mRect.bottom};

        float leftTopPointMap[] = new float[2];
        float rightTopPointMap[] = new float[2];
        float leftbottomPointMap[] = new float[2];
        float rightBottomPointMap[] = new float[2];
        Matrix m1 = new Matrix();
        m1.postRotate(getDegree(), mRect.centerX(), mRect.centerY());
        m1.mapPoints(leftTopPointMap, leftTopPoint);//计算map后的点
        m1.mapPoints(rightTopPointMap, rightTopPoint);
        m1.mapPoints(leftbottomPointMap, leftbottomPoint);
        m1.mapPoints(rightBottomPointMap, rightBottomPoint);

        Line line = new Line(leftTopPointMap[0], -leftTopPointMap[1], leftbottomPointMap[0], -leftbottomPointMap[1]);
        double x, y;
        if (line.isHrizontal()) {
            x = dy;
            y = 0;
        } else if (line.isVertical()) {
            x = 0;
            y = dy;
        } else {
            int location1 = MathUtil.getLocation(leftTopPointMap[0] - leftbottomPointMap[0], leftTopPointMap[1] - leftbottomPointMap[1]);
            double degree1 = MathUtil.getDegreeFromX(line, location1);
            if (degree1 < 90) {
                double radians = Math.toRadians(degree1);
                if (dy < 0) {
                    x = -dy * Math.cos(radians);
                    y = dy * Math.sin(radians);
                } else {
                    x = -dy * Math.cos(radians);
                    y = dy * Math.sin(radians);
                }
            } else if (degree1 < 180) {
                double radians = Math.toRadians(180 - degree1);
                if (dy < 0) {
                    x = dy * Math.cos(radians);
                    y = dy * Math.sin(radians);
                } else {
                    x = dy * Math.cos(radians);
                    y = dy * Math.sin(radians);
                }
            } else if (degree1 < 270) {
                double radians = Math.toRadians(270 - degree1);
                if (dy < 0) {
                    x = dy * Math.sin(radians);
                    y = -dy * Math.cos(radians);
                } else {
                    x = dy * Math.sin(radians);
                    y = -dy * Math.cos(radians);
                }
            } else {
                double radians = Math.toRadians(360 - degree1);
                if (dy < 0) {
                    x = -dy * Math.cos(radians);
                    y = -dy * Math.sin(radians);
                } else {
                    x = -dy * Math.cos(radians);
                    y = -dy * Math.sin(radians);
                }
            }
        }
        float leftTopPointMapResult[] = new float[2];
        float rightTopPointMapResult[] = new float[2];
        leftTopPointMapResult[0] = leftTopPointMap[0] + (float) x;
        leftTopPointMapResult[1] = leftTopPointMap[1] + (float) y;
        rightTopPointMapResult[0] = rightTopPointMap[0] + (float) x;
        rightTopPointMapResult[1] = rightTopPointMap[1] + (float) y;

        RectF rectF = MathUtil.point2RectF(leftTopPointMapResult, leftbottomPointMap, rightTopPointMapResult, rightBottomPointMap);
        m1.reset();
        m1.postRotate(-getDegree(), rectF.centerX(), rectF.centerY());
        m1.mapPoints(leftTopPointMapResult);
        m1.mapPoints(leftbottomPointMap);
        m1.mapPoints(rightTopPointMapResult);
        m1.mapPoints(rightBottomPointMap);
        rectF = MathUtil.point2RectF(leftTopPointMapResult, leftbottomPointMap, rightTopPointMapResult, rightBottomPointMap);

        if (rectF.width() >= SMALLEST_SIZE) {
            mRect = new RectF(rectF);
            mRect.left = Math.min(mRect.left, mRect.right);
            countOtherRect();
        }
    }

    /**
     * 原理同上
     *
     * @param dy
     */
    public void operationBottom(float dy) {
        float leftTopPoint[] = new float[]{mRect.left, mRect.top};
        float rightTopPoint[] = new float[]{mRect.right, mRect.top};
        float leftbottomPoint[] = new float[]{mRect.left, mRect.bottom};
        float rightBottomPoint[] = new float[]{mRect.right, mRect.bottom};

        float leftTopPointMap[] = new float[2];
        float rightTopPointMap[] = new float[2];
        float leftbottomPointMap[] = new float[2];
        float rightBottomPointMap[] = new float[2];

        Matrix m1 = new Matrix();
        m1.postRotate(getDegree(), mRect.centerX(), mRect.centerY());
        m1.mapPoints(leftTopPointMap, leftTopPoint);//计算map后的点
        m1.mapPoints(rightTopPointMap, rightTopPoint);
        m1.mapPoints(leftbottomPointMap, leftbottomPoint);
        m1.mapPoints(rightBottomPointMap, rightBottomPoint);

        Line line = new Line(leftbottomPointMap[0], -leftbottomPointMap[1], leftTopPointMap[0], -leftTopPointMap[1]);
        double x, y;
        if (line.isHrizontal()) {
            x = dy;
            y = 0;
        } else if (line.isVertical()) {
            x = 0;
            y = dy;
        } else {
            int location1 = MathUtil.getLocation(leftbottomPointMap[0] - leftTopPointMap[0], leftbottomPointMap[1] - leftTopPointMap[1]);
            double degree1 = MathUtil.getDegreeFromX(line, location1);
            if (degree1 < 90) {
                double radians = Math.toRadians(degree1);
                if (dy < 0) {
                    x = dy * Math.cos(radians);
                    y = -dy * Math.sin(radians);
                } else {
                    x = dy * Math.cos(radians);
                    y = -dy * Math.sin(radians);
                }
            } else if (degree1 < 180) {
                double radians = Math.toRadians(180 - degree1);
                if (dy < 0) {
                    x = -dy * Math.cos(radians);
                    y = -dy * Math.sin(radians);
                } else {
                    x = -dy * Math.cos(radians);
                    y = -dy * Math.sin(radians);
                }
            } else if (degree1 < 270) {
                double radians = Math.toRadians(270 - degree1);
                if (dy < 0) {
                    x = -dy * Math.sin(radians);
                    y = dy * Math.cos(radians);
                } else {
                    x = -dy * Math.sin(radians);
                    y = dy * Math.cos(radians);
                }
            } else {
                double radians = Math.toRadians(360 - degree1);
                if (dy < 0) {
                    x = dy * Math.cos(radians);
                    y = dy * Math.sin(radians);
                } else {
                    x = dy * Math.cos(radians);
                    y = dy * Math.sin(radians);
                }
            }
        }
        float leftBottomPointMapResult[] = new float[2];
        float rightbottomPointMapResult[] = new float[2];
        leftBottomPointMapResult[0] = leftbottomPointMap[0] + (float) x;
        leftBottomPointMapResult[1] = leftbottomPointMap[1] + (float) y;
        rightbottomPointMapResult[0] = rightBottomPointMap[0] + (float) x;
        rightbottomPointMapResult[1] = rightBottomPointMap[1] + (float) y;

        RectF rectF = MathUtil.point2RectF(leftTopPointMap, leftBottomPointMapResult, rightTopPointMap, rightbottomPointMapResult);
        m1.reset();
        m1.postRotate(-getDegree(), rectF.centerX(), rectF.centerY());
        m1.mapPoints(leftTopPointMap);
        m1.mapPoints(leftBottomPointMapResult);
        m1.mapPoints(rightTopPointMap);
        m1.mapPoints(rightbottomPointMapResult);
        rectF = MathUtil.point2RectF(leftTopPointMap, leftBottomPointMapResult, rightTopPointMap, rightbottomPointMapResult);

        if (rectF.width() >= SMALLEST_SIZE) {
            mRect = new RectF(rectF);
            mRect.left = Math.min(mRect.left, mRect.right);
            countOtherRect();
        }
    }

    public RectF getLeftOperationRect() {
        return mLeftOperationRect;
    }

    public RectF getTopOperationRect() {
        return mTopOperationRect;
    }

    public RectF getRightOperationRect() {
        return mRightOperationRect;
    }

    public RectF getBottomOperationRect() {
        return mBottomOperationRect;
    }

    public class PathBean {
        public Path path;
        public Paint paint;

        public PathBean(Path path, Paint paint) {
            this.path = new Path(path);
            this.paint = new Paint(paint);
        }
    }

    public class AdjustParam {
        public float tone;
        public float saturation;
        public float brightness;
        public float alpha;

        public AdjustParam(float tone, float saturation, float brightness, float alpha) {
            this.tone = tone;
            this.saturation = saturation;
            this.brightness = brightness;
            this.alpha = alpha;
        }

        public AdjustParam(AdjustParam param) {
            this.tone = param.tone;
            this.saturation = param.saturation;
            this.brightness = param.brightness;
            this.alpha = param.alpha;
        }

        public void set(AdjustParam param) {
            this.tone = param.tone;
            this.saturation = param.saturation;
            this.brightness = param.brightness;
            this.alpha = param.alpha;
        }

        public void set(float tone, float saturation, float brightness, float alpha) {
            this.tone = tone;
            this.saturation = saturation;
            this.brightness = brightness;
            this.alpha = alpha;
        }
    }

    public boolean isDownloadOnGP() {
        return mEmojiBean.isDownloadOnGP();
    }

    public String getPkgName() {
        return mEmojiBean.getPackageName();
    }
}
